﻿using System;
using System.Collections.Generic;
using GeoAPI.Geometries;
using YJKGridTopologyCal.Algorithm.Locate;
using YJKGridTopologyCal.Geometries.Utilities;

namespace YJKGridTopologyCal.Geometries.Prepared
{
	internal abstract class PreparedPolygonPredicate
	{
		protected PreparedPolygonPredicate(PreparedPolygon prepPoly)
		{
			this.prepPoly = prepPoly;
			this._targetPointLocator = prepPoly.PointLocator;
		}

		protected bool IsAllTestComponentsInTarget(IGeometry testGeom)
		{
			foreach (Coordinate p in ((IEnumerable<Coordinate>)ComponentCoordinateExtracter.GetCoordinates(testGeom)))
			{
				if (this._targetPointLocator.Locate(p) == Location.Exterior)
				{
					return false;
				}
			}
			return true;
		}

		protected bool IsAllTestComponentsInTargetInterior(IGeometry testGeom)
		{
			foreach (Coordinate p in ((IEnumerable<Coordinate>)ComponentCoordinateExtracter.GetCoordinates(testGeom)))
			{
				if (this._targetPointLocator.Locate(p) != Location.Interior)
				{
					return false;
				}
			}
			return true;
		}

		protected bool IsAnyTestComponentInTarget(IGeometry testGeom)
		{
			foreach (Coordinate p in ((IEnumerable<Coordinate>)ComponentCoordinateExtracter.GetCoordinates(testGeom)))
			{
				if (this._targetPointLocator.Locate(p) != Location.Exterior)
				{
					return true;
				}
			}
			return false;
		}

		protected bool IsAnyTestComponentInTargetInterior(IGeometry testGeom)
		{
			foreach (Coordinate p in ((IEnumerable<Coordinate>)ComponentCoordinateExtracter.GetCoordinates(testGeom)))
			{
				if (this._targetPointLocator.Locate(p) == Location.Interior)
				{
					return true;
				}
			}
			return false;
		}

		protected bool IsAnyTargetComponentInAreaTest(IGeometry testGeom, IList<Coordinate> targetRepPts)
		{
			IPointOnGeometryLocator pointOnGeometryLocator = new SimplePointInAreaLocator(testGeom);
			foreach (Coordinate p in targetRepPts)
			{
				if (pointOnGeometryLocator.Locate(p) != Location.Exterior)
				{
					return true;
				}
			}
			return false;
		}

		protected PreparedPolygon prepPoly;

		private readonly IPointOnGeometryLocator _targetPointLocator;
	}
}
